/*
 * EmptySpaceMgr.cpp
 *
 *  Created on: Sep 18, 2011
 *      Author:
 */

#include "EmptySpaceMgr.h"

EmptySpaceMgr::EmptySpaceMgr(string xfilePath) {
	// open file
	filePath = xfilePath;
	_file.open(filePath.c_str(),ios::out | ios::in | ios::binary);

	if (!_file.is_open())
		_file.open(filePath.c_str(), ios::in | ios::out | ios::trunc | ios::binary);

	//TODO: Mejorar usando el logger.
	if (!_file.is_open())
		throw ios_base::failure("cannot create file at \"" + filePath + "\".");
}

EmptySpaceMgr::~EmptySpaceMgr() {
	// close file
	_file.flush();
	_file.close();
}

bool EmptySpaceMgr::add(unsigned long _regId) {
	if (!_file.is_open())
		return false;

	_file.seekp(0,ios::end);

	_file.write(reinterpret_cast<char*>(&_regId), sizeof(unsigned long));

    _file.flush();

	return true;
}


bool EmptySpaceMgr::has(unsigned long _regId) {

	_file.seekg(0,ios::end);
	long tail = _file.tellg();
	_file.seekg(0,ios::beg);
	if (tail > 0) {
		while (_file.eof() == false) {
			unsigned long _readRegId = -1;
			_file.read(reinterpret_cast<char*>(&_readRegId), sizeof(unsigned long));

			if (_readRegId == _regId) {
				return true;
			}
		}
	}
	return false;
}

void EmptySpaceMgr::deleteAll() {
	_file.close();
	_file.open(filePath.c_str(), ios::in | ios::out | ios::trunc | ios::binary);
}


bool EmptySpaceMgr::get(unsigned long *_regId) {
	if (!_file.is_open())
			return false;

	_file.seekg(0,ios::end);

	long tail = _file.tellg();

	if (tail > 0) {
		unsigned long _readRegId = 0;

		_file.seekg(tail - sizeof(unsigned long),ios::beg);
		_file.read(reinterpret_cast<char*>(&_readRegId), sizeof(unsigned long));

		*_regId = _readRegId;

        /// read all file content into an array
		_file.seekg(0,ios::end);
        unsigned long lastPos =_file.tellg();
		unsigned long top = lastPos/sizeof (unsigned long);
		unsigned long aULong;
		// 0,1,2,3 - 4,5,6,7 - 8,9,10,11 - 12,13,14,15
		vector<unsigned long> allRegs;

		_file.seekg(0,ios::beg);
		for (unsigned long i = 0; i < top -1; i++) {
			_file.read(reinterpret_cast<char*>(&aULong), sizeof(unsigned long));

			allRegs.push_back(aULong);
		}
        /// truncate the file
		_file.close();
		_file.open(filePath.c_str(),ios::out | ios::in | ios::binary | ios::trunc);


        /// dump all the content
		/// escribo los registros
		for (unsigned long i = 0; i < top -1; i++) {
			unsigned long& l = allRegs.at(i);
			unsigned long val = l;

			_file.write(reinterpret_cast<char*>(&val), sizeof(unsigned long));
		}

		_file.flush();
		return true;
	}

	return false;
}


